package com.player;

import org.bytedeco.javacv.Frame;

import javax.swing.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class VideoThread extends Thread {
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("mm:ss.SSS");

    @Override
    public void run() {
        MyCanvasFrame canvasFrame = new MyCanvasFrame("播放器");
        canvasFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        canvasFrame.init();
        try {
            while (canvasFrame.isVisible()) {
                Frame frame = null;
                try {
                    frame = Data.VIDEO_QUEUE.poll(1, TimeUnit.SECONDS);
                    if (shouldTerminate(frame)) break;

                    synchronizeFrameWithAudio(frame, canvasFrame);
                } catch (InterruptedException e) {
                    handleInterruption();
                    break;
                } catch (Exception e) {
                    handleGenericException(frame, e);
                } finally {
                    closeFrame(frame);
                }
            }
        } finally {
            canvasFrame.dispose();
        }
    }

    private boolean shouldTerminate(Frame frame) {
        return frame == null || Data.closed.get();
    }

    private void synchronizeFrameWithAudio(Frame frame, MyCanvasFrame canvasFrame)
            throws InterruptedException {
        while (true) {
            if (Data.sourceDataLine == null) {
                throw new IllegalStateException("Audio device not initialized");
            }

            long audioTs = Data.sourceDataLine.getMicrosecondPosition();
            long videoTs = frame.timestamp;

            if (videoTs > audioTs) {
                Thread.sleep(5);
                continue;
            }

            renderFrame(frame, canvasFrame);
            break;
        }
    }

    private void renderFrame(Frame frame, MyCanvasFrame canvasFrame) {
        canvasFrame.showImage(frame);
    }
    private void handleInterruption() {
        Thread.currentThread().interrupt();
        System.out.println("Video playback was interrupted");
    }

    private void handleGenericException(Frame frame, Exception e) {
        System.err.printf("Error processing frame [%s]: %s%n",
                frame != null ? frame.toString() : "null", e.getMessage());
        throw new RuntimeException(e);
    }

    private void closeFrame(Frame frame) {
        try {
            if (frame != null) frame.close();
        } catch (Exception e) {
            System.err.println("Frame closing failed: " + e.getMessage());
        }
    }
}

